home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / jpsrc2.zip / JWRJFIF.C < prev    next >
C/C++ Source or Header  |  1991-12-12  |  12KB  |  473 lines

  1. /*
  2.  * jwrjfif.c
  3.  *
  4.  * Copyright (C) 1991, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to write standard JPEG file headers/markers.
  9.  * The file format created is a raw JPEG data stream with (optionally) an
  10.  * APP0 marker per the JFIF spec.  This will handle baseline and
  11.  * JFIF-convention JPEG files, although there is currently no provision
  12.  * for inserting a thumbnail image in the JFIF header.
  13.  *
  14.  * These routines may need modification for non-Unix environments or
  15.  * specialized applications.  As they stand, they assume output to
  16.  * an ordinary stdio stream.  However, the changes to write to something
  17.  * else are localized in the macros appearing just below.
  18.  *
  19.  * These routines are invoked via the methods write_file_header,
  20.  * write_scan_header, write_jpeg_data, write_scan_trailer, and
  21.  * write_file_trailer.
  22.  */
  23.  
  24. #include "jinclude.h"
  25.  
  26. #ifdef JFIF_SUPPORTED
  27.  
  28.  
  29. /*
  30.  * To output to something other than a stdio stream, you'd need to redefine
  31.  * these macros.
  32.  */
  33.  
  34. /* Write a single byte */
  35. #define emit_byte(cinfo,x)  putc((x), cinfo->output_file)
  36.  
  37. /* Write some bytes from a (char *) buffer */
  38. #define WRITE_BYTES(cinfo,dataptr,datacount)  \
  39.   { if (FWRITE(cinfo->output_file, dataptr, datacount) \
  40.     != (size_t) (datacount)) \
  41.       ERREXIT(cinfo->emethods, "Output file write error"); }
  42.  
  43. /* Clean up and verify successful output */
  44. #define CHECK_OUTPUT(cinfo)  \
  45.   { fflush(cinfo->output_file); \
  46.     if (ferror(cinfo->output_file)) \
  47.       ERREXIT(cinfo->emethods, "Output file write error"); }
  48.  
  49.  
  50. /* End of stdio-specific code. */
  51.  
  52.  
  53. typedef enum {            /* JPEG marker codes */
  54.   M_SOF0  = 0xc0,
  55.   M_SOF1  = 0xc1,
  56.   M_SOF2  = 0xc2,
  57.   M_SOF3  = 0xc3,
  58.   
  59.   M_SOF5  = 0xc5,
  60.   M_SOF6  = 0xc6,
  61.   M_SOF7  = 0xc7,
  62.   
  63.   M_JPG   = 0xc8,
  64.   M_SOF9  = 0xc9,
  65.   M_SOF10 = 0xca,
  66.   M_SOF11 = 0xcb,
  67.   
  68.   M_SOF13 = 0xcd,
  69.   M_SOF14 = 0xce,
  70.   M_SOF15 = 0xcf,
  71.   
  72.   M_DHT   = 0xc4,
  73.   
  74.   M_DAC   = 0xcc,
  75.   
  76.   M_RST0  = 0xd0,
  77.   M_RST1  = 0xd1,
  78.   M_RST2  = 0xd2,
  79.   M_RST3  = 0xd3,
  80.   M_RST4  = 0xd4,
  81.   M_RST5  = 0xd5,
  82.   M_RST6  = 0xd6,
  83.   M_RST7  = 0xd7,
  84.   
  85.   M_SOI   = 0xd8,
  86.   M_EOI   = 0xd9,
  87.   M_SOS   = 0xda,
  88.   M_DQT   = 0xdb,
  89.   M_DNL   = 0xdc,
  90.   M_DRI   = 0xdd,
  91.   M_DHP   = 0xde,
  92.   M_EXP   = 0xdf,
  93.   
  94.   M_APP0  = 0xe0,
  95.   M_APP15 = 0xef,
  96.   
  97.   M_JPG0  = 0xf0,
  98.   M_JPG13 = 0xfd,
  99.   M_COM   = 0xfe,
  100.   
  101.   M_TEM   = 0x01,
  102.   
  103.   M_ERROR = 0x100
  104. } JPEG_MARKER;
  105.  
  106.  
  107. LOCAL void
  108. emit_marker (compress_info_ptr cinfo, JPEG_MARKER mark)
  109. /* Emit a marker code */
  110. {
  111.   emit_byte(cinfo, 0xFF);
  112.   emit_byte(cinfo, mark);
  113. }
  114.  
  115.  
  116. LOCAL void
  117. emit_2bytes (compress_info_ptr cinfo, int value)
  118. /* Emit a 2-byte integer; these are always MSB first in JPEG files */
  119. {
  120.   emit_byte(cinfo, (value >> 8) & 0xFF);
  121.   emit_byte(cinfo, value & 0xFF);
  122. }
  123.  
  124.  
  125. LOCAL int
  126. emit_dqt (compress_info_ptr cinfo, int index)
  127. /* Emit a DQT marker */
  128. /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
  129. {
  130.   QUANT_TBL_PTR data = cinfo->quant_tbl_ptrs[index];
  131.   int prec = 0;
  132.   int i;
  133.   
  134.   for (i = 0; i < DCTSIZE2; i++) {
  135.     if (data[i] > 255)
  136.       prec = 1;
  137.   }
  138.  
  139.   emit_marker(cinfo, M_DQT);
  140.   
  141.   emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
  142.   
  143.   emit_byte(cinfo, index + (prec<<4));
  144.   
  145.   for (i = 0; i < DCTSIZE2; i++) {
  146.     if (prec)
  147.       emit_byte(cinfo, data[i] >> 8);
  148.     emit_byte(cinfo, data[i] & 0xFF);
  149.   }
  150.  
  151.   return prec;
  152. }
  153.  
  154.  
  155. LOCAL void
  156. emit_dht (compress_info_ptr cinfo, int index, boolean is_ac)
  157. /* Emit a DHT marker */
  158. {
  159.   HUFF_TBL * htbl;
  160.   int length, i;
  161.   
  162.   if (is_ac) {
  163.     htbl = cinfo->ac_huff_tbl_ptrs[index];
  164.     index += 0x10;        /* output index has AC bit set */
  165.   } else {
  166.     htbl = cinfo->dc_huff_tbl_ptrs[index];
  167.   }
  168.   
  169.   if (! htbl->sent_table) {
  170.     emit_marker(cinfo, M_DHT);
  171.     
  172.     length = 0;
  173.     for (i = 1; i <= 16; i++)
  174.       length += htbl->bits[i];
  175.     
  176.     emit_2bytes(cinfo, length + 2 + 1 + 16);
  177.     emit_byte(cinfo, index);
  178.     
  179.     for (i = 1; i <= 16; i++)
  180.       emit_byte(cinfo, htbl->bits[i]);
  181.     
  182.     for (i = 0; i < length; i++)
  183.       emit_byte(cinfo, htbl->huffval[i]);
  184.     
  185.     htbl->sent_table = TRUE;
  186.   }
  187. }
  188.  
  189.  
  190. LOCAL void
  191. emit_dac (compress_info_ptr cinfo)
  192. /* Emit a DAC marker */
  193. /* Since the useful info is so small, we want to emit all the tables in */
  194. /* one DAC marker.  Therefore this routine does its own scan of the table. */
  195. {
  196.   char dc_in_use[NUM_ARITH_TBLS];
  197.   char ac_in_use[NUM_ARITH_TBLS];
  198.   int length, i;
  199.   
  200.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  201.     dc_in_use[i] = ac_in_use[i] = 0;
  202.   
  203.   for (i = 0; i < cinfo->num_components; i++) {
  204.     dc_in_use[cinfo->comp_info[i].dc_tbl_no] = 1;
  205.     ac_in_use[cinfo->comp_info[i].ac_tbl_no] = 1;
  206.   }
  207.   
  208.   length = 0;
  209.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  210.     length += dc_in_use[i] + ac_in_use[i];
  211.   
  212.   emit_marker(cinfo, M_DAC);
  213.   
  214.   emit_2bytes(cinfo, length*2 + 2);
  215.   
  216.   for (i = 0; i < NUM_ARITH_TBLS; i++) {
  217.     if (dc_in_use[i]) {
  218.       emit_byte(cinfo, i);
  219.       emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
  220.     }
  221.     if (ac_in_use[i]) {
  222.       emit_byte(cinfo, i + 0x10);
  223.       emit_byte(cinfo, cinfo->arith_ac_K[i]);
  224.     }
  225.   }
  226. }
  227.  
  228.  
  229. LOCAL void
  230. emit_dri (compress_info_ptr cinfo)
  231. /* Emit a DRI marker */
  232. {
  233.   emit_marker(cinfo, M_DRI);
  234.   
  235.   emit_2bytes(cinfo, 4);    /* fixed length */
  236.  
  237.   emit_2bytes(cinfo, (int) cinfo->restart_interval);
  238. }
  239.  
  240.  
  241. LOCAL void
  242. emit_sof (compress_info_ptr cinfo, JPEG_MARKER code)
  243. /* Emit a SOF marker */
  244. {
  245.   int i;
  246.   
  247.   emit_marker(cinfo, code);
  248.   
  249.   emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
  250.  
  251.   if (cinfo->image_height > 65535L || cinfo->image_width > 65535L)
  252.     ERREXIT(cinfo->emethods, "Maximum image dimension for JFIF is 65535 pixels");
  253.  
  254.   emit_byte(cinfo, cinfo->data_precision);
  255.   emit_2bytes(cinfo, (int) cinfo->image_height);
  256.   emit_2bytes(cinfo, (int) cinfo->image_width);
  257.  
  258.   emit_byte(cinfo, cinfo->num_components);
  259.  
  260.   for (i = 0; i < cinfo->num_components; i++) {
  261.     emit_byte(cinfo, cinfo->comp_info[i].component_id);
  262.     emit_byte(cinfo, (cinfo->comp_info[i].h_samp_factor << 4)
  263.              + cinfo->comp_info[i].v_samp_factor);
  264.     emit_byte(cinfo, cinfo->comp_info[i].quant_tbl_no);
  265.   }
  266. }
  267.  
  268.  
  269. LOCAL void
  270. emit_sos (compress_info_ptr cinfo)
  271. /* Emit a SOS marker */
  272. {
  273.   int i;
  274.   
  275.   emit_marker(cinfo, M_SOS);
  276.   
  277.   emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
  278.   
  279.   emit_byte(cinfo, cinfo->comps_in_scan);
  280.   
  281.   for (i = 0; i < cinfo->comps_in_scan; i++) {
  282.     emit_byte(cinfo, cinfo->cur_comp_info[i]->component_id);
  283.     emit_byte(cinfo, (cinfo->cur_comp_info[i]->dc_tbl_no << 4)
  284.              + cinfo->cur_comp_info[i]->ac_tbl_no);
  285.   }
  286.  
  287.   emit_byte(cinfo, 0);        /* Spectral selection start */
  288.   emit_byte(cinfo, DCTSIZE2-1);    /* Spectral selection end */
  289.   emit_byte(cinfo, 0);        /* Successive approximation */
  290. }
  291.  
  292.  
  293. LOCAL void
  294. emit_jfif_app0 (compress_info_ptr cinfo)
  295. /* Emit a JFIF-compliant APP0 marker */
  296. {
  297.   /*
  298.    * Length of APP0 block    (2 bytes)
  299.    * Block ID            (4 bytes - ASCII "JFIF")
  300.    * Zero byte            (1 byte to terminate the ID string)
  301.    * Version Major, Minor    (2 bytes - 0x01, 0x01)
  302.    * Units            (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
  303.    * Xdpu            (2 bytes - dots per unit horizontal)
  304.    * Ydpu            (2 bytes - dots per unit vertical)
  305.    * Thumbnail X size        (1 byte)
  306.    * Thumbnail Y size        (1 byte)
  307.    */
  308.   
  309.   emit_marker(cinfo, M_APP0);
  310.   
  311.   emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
  312.  
  313.   emit_byte(cinfo, 'J');    /* Identifier */
  314.   emit_byte(cinfo, 'F');
  315.   emit_byte(cinfo, 'I');
  316.   emit_byte(cinfo, 'F');
  317.   emit_byte(cinfo, 0);
  318.   emit_byte(cinfo, 1);        /* Major version */
  319.   emit_byte(cinfo, 1);        /* Minor version */
  320.   emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
  321.   emit_2bytes(cinfo, (int) cinfo->X_density);
  322.   emit_2bytes(cinfo, (int) cinfo->Y_density);
  323.   emit_byte(cinfo, 0);        /* No thumbnail image */
  324.   emit_byte(cinfo, 0);
  325. }
  326.  
  327.  
  328. /*
  329.  * Write the file header.
  330.  */
  331.  
  332.  
  333. METHODDEF void
  334. write_file_header (compress_info_ptr cinfo)
  335. {
  336.   char qt_in_use[NUM_QUANT_TBLS];
  337.   int i, prec;
  338.   boolean is_baseline;
  339.   
  340.   emit_marker(cinfo, M_SOI);    /* first the SOI */
  341.  
  342.   if (cinfo->write_JFIF_header)    /* next an optional JFIF APP0 */
  343.     emit_jfif_app0(cinfo);
  344.  
  345.   /* Emit DQT for each quantization table. */
  346.   /* Note that doing it here means we can't adjust the QTs on-the-fly. */
  347.   /* If we did want to do that, we'd have a problem with checking precision */
  348.   /* for the is_baseline determination. */
  349.  
  350.   for (i = 0; i < NUM_QUANT_TBLS; i++)
  351.     qt_in_use[i] = 0;
  352.  
  353.   for (i = 0; i < cinfo->num_components; i++)
  354.     qt_in_use[cinfo->comp_info[i].quant_tbl_no] = 1;
  355.  
  356.   prec = 0;
  357.   for (i = 0; i < NUM_QUANT_TBLS; i++) {
  358.     if (qt_in_use[i])
  359.       prec += emit_dqt(cinfo, i);
  360.   }
  361.   /* now prec is nonzero iff there are any 16-bit quant tables. */
  362.  
  363.   if (cinfo->restart_interval)
  364.     emit_dri(cinfo);
  365.  
  366.   /* Check for a non-baseline specification. */
  367.   /* Note we assume that Huffman table numbers won't be changed later. */
  368.   is_baseline = TRUE;
  369.   if (cinfo->arith_code || (cinfo->data_precision != 8))
  370.     is_baseline = FALSE;
  371.   for (i = 0; i < cinfo->num_components; i++) {
  372.     if (cinfo->comp_info[i].dc_tbl_no > 1 || cinfo->comp_info[i].ac_tbl_no > 1)
  373.       is_baseline = FALSE;
  374.   }
  375.   if (prec && is_baseline) {
  376.     is_baseline = FALSE;
  377.     /* If it's baseline except for quantizer size, warn the user */
  378.     TRACEMS(cinfo->emethods, 0,
  379.         "Caution: quantization tables are too coarse for baseline JPEG");
  380.   }
  381.  
  382.  
  383.   /* Emit the proper SOF marker */
  384.   if (cinfo->arith_code)
  385.     emit_sof(cinfo, M_SOF9);    /* SOF code for arithmetic coding */
  386.   else if (is_baseline)
  387.     emit_sof(cinfo, M_SOF0);    /* SOF code for baseline implementation */
  388.   else
  389.     emit_sof(cinfo, M_SOF1);    /* SOF code for non-baseline Huffman file */
  390. }
  391.  
  392.  
  393. /*
  394.  * Write the start of a scan (everything through the SOS marker).
  395.  */
  396.  
  397. METHODDEF void
  398. write_scan_header (compress_info_ptr cinfo)
  399. {
  400.   int i;
  401.  
  402.   if (cinfo->arith_code) {
  403.     /* Emit arith conditioning info.  We will have some duplication
  404.      * if the file has multiple scans, but it's so small it's hardly
  405.      * worth worrying about.
  406.      */
  407.     emit_dac(cinfo);
  408.   } else {
  409.     /* Emit Huffman tables.  Note that emit_dht takes care of
  410.      * suppressing duplicate tables.
  411.      */
  412.     for (i = 0; i < cinfo->comps_in_scan; i++) {
  413.       emit_dht(cinfo, cinfo->cur_comp_info[i]->dc_tbl_no, FALSE);
  414.       emit_dht(cinfo, cinfo->cur_comp_info[i]->ac_tbl_no, TRUE);
  415.     }
  416.   }
  417.  
  418.   emit_sos(cinfo);
  419. }
  420.  
  421.  
  422. /*
  423.  * Write some bytes of compressed data within a scan.
  424.  */
  425.  
  426. METHODDEF void
  427. write_jpeg_data (compress_info_ptr cinfo, char *dataptr, int datacount)
  428. {
  429.   WRITE_BYTES(cinfo, dataptr, datacount);
  430. }
  431.  
  432.  
  433. /*
  434.  * Finish up after a compressed scan (series of write_jpeg_data calls).
  435.  */
  436.  
  437. METHODDEF void
  438. write_scan_trailer (compress_info_ptr cinfo)
  439. {
  440.   /* no work needed in this format */
  441. }
  442.  
  443.  
  444. /*
  445.  * Finish up at the end of the file.
  446.  */
  447.  
  448. METHODDEF void
  449. write_file_trailer (compress_info_ptr cinfo)
  450. {
  451.   emit_marker(cinfo, M_EOI);
  452.   /* Make sure we wrote the output file OK */
  453.   CHECK_OUTPUT(cinfo);
  454. }
  455.  
  456.  
  457. /*
  458.  * The method selection routine for standard JPEG header writing.
  459.  * This should be called from c_ui_method_selection if appropriate.
  460.  */
  461.  
  462. GLOBAL void
  463. jselwjfif (compress_info_ptr cinfo)
  464. {
  465.   cinfo->methods->write_file_header = write_file_header;
  466.   cinfo->methods->write_scan_header = write_scan_header;
  467.   cinfo->methods->write_jpeg_data = write_jpeg_data;
  468.   cinfo->methods->write_scan_trailer = write_scan_trailer;
  469.   cinfo->methods->write_file_trailer = write_file_trailer;
  470. }
  471.  
  472. #endif /* JFIF_SUPPORTED */
  473.